#include "Zlist.h"
#include "ZSpiritImgFile.h"
#include "ZMapFile.h"
#include "ZEventStruct.h"
#include "Baseconst.h"
#pragma once

typedef struct _TimeCallBack
{
	unsigned short int MaxFrame;
	unsigned short int CurFrame;
	bool IsOver;
	LPVOID PObj;
	LPVOID (*CallBack)(LPVOID lp,LPVOID argv[]);
	LPVOID *Argv;
}TTimeCallBack,*PTimeCallBack;

namespace Zdib
{
	class CContainer:virtual public IReferenceCounted
	{
	public:
		CContainer(CContainer *parent=NULL);
		virtual ~CContainer();
		
		void SetParent(CContainer *parent);
		void AddChildren(CContainer *chi);
		void DelChildren(CContainer *chi);
		void ChanegChidrenZ(CContainer *chi,int z);
		void SetZ(int z);
		void EvaluationZ(int z);
		int GetZ();
		void SetID(int id);
		int GetID();
		void SetIsNowFocus(bool nowfocus)
		{
			m_IsNowFocus=nowfocus;
		}
		TPos GetPos();
		TPos ScreenPos();
		int GetH()
		{
			return H;
		}
		int GetW()
		{
			return W;
		}
		CContainer *GetParent();
		void SetShow(bool show)
		{
			m_Show=show;
			if(m_Show)
			{}
			else
			{
				if(m_IsNowFocus)
				{
					root->SetOnFocus(NULL);
				}
			}
		}
		bool GetShow()
		{
			return m_Show;
		}
		virtual TPos GetScreenPos();
		virtual LPVOID GetEventClass()
		{
			return NULL;
		}
		virtual void Draw()
		{
			int i;
			CContainer *temp;
			if(!m_Show)
				return;
			for(i=0;i<m_Childrens.count;i++)
			{
				temp=(CContainer *)m_Childrens.items(i);
				temp->Draw();
			}
			if(ScreenX!=OldScreenX || ScreenY!=OldScreenY)
				m_RefrashDrawPos=true;
			else
				m_RefrashDrawPos=false;
			OldScreenX=ScreenX;
			OldScreenY=ScreenY;
		};
		virtual CImgFile *GetCurImg()
		{
			if(m_Parent)
			{
				return m_Parent->GetCurImg();
			}
			else
				return ((CContainer *)root)->GetCurImg();
		};
		virtual void SetPos(int x,int y)
		{
			int i;
			X=x;
			Y=y;
			TPos pos;
			pos=GetScreenPos();
			ScreenX=pos.x;
			ScreenY=pos.y;
			CContainer *temp;
			for(i=0;i<m_Childrens.count;i++)
			{
				temp=(CContainer *)m_Childrens.items(i);
				temp->SetPos(temp->X,temp->Y);
			}
		};
		virtual CSpiritImgFile *GetImgForPath(char *filename){return NULL;};
		virtual CMapFile *GetMapForPath(char *filename){return NULL;};
		void SetRoot(CContainer *lp);
		CContainer *GetRoot()
		{
			return root;
		}
		virtual PTimeCallBack SetCallBack(LPVOID po,LPVOID (*CallBack)(LPVOID lp,LPVOID argv[]),unsigned short int frame,LPVOID argv[]=NULL);
		virtual void FreeCallBack(PTimeCallBack t);
		virtual HDC GetHDC(){return NULL;};
		virtual bool OnEvent(const TEvent& ev)
		{
			if(this->myEventReceiver)
			{
				return this->myEventReceiver->OnEvent(ev);
			}
			else
			{
				return m_Parent ? m_Parent->OnEvent(ev) : false;
			}
		};
		virtual void SetEventReceiver(Zdib::CEventReceiver * myevent);
		virtual CBitBmp *GetMyImg(){return NULL;};
		virtual bool isInMyScope(int x,int y)
		{
			int px,py;
			CBitBmp *temp;
			px=x-ScreenX;
			py=y-ScreenY;
			if(!m_Show)
				return false;
			if(px<0 || py<0)
				return false;
			temp=GetMyImg();
			if(temp)
			{
				return temp->isPointInSide(px,py);
			}
			return false;
		};
		virtual CContainer *GetObjForPoint(int x,int y)
		{
			CContainer *temp=0;
			CContainer *target=0;
			int i;
			for(i=m_Childrens.count-1;i>=0;i--)
			{
				temp=(CContainer *)m_Childrens.items(i);
				if(temp)
				{
					target=temp->GetObjForPoint(x,y);
					if(target)
						return target;
				}
			}
			if(isInMyScope(x,y))
			{
				if(myEventReceiver!=NULL)
					return this;
				else
					return this->GetParent();
			}
			return target;
		};

	protected:
		int m_IDMax;
		int Z;
		int ID;

		int W;
		int H;
		int X;
		int Y;
		int OldScreenX;
		int OldScreenY;
		int ScreenX;
		int ScreenY;
		bool m_Show;
		bool m_IsNowFocus;
		CContainer *m_Parent;
		TDrawPosValue m_DPosValue;

		bool m_RefrashDrawPos;
		TZList *m_CallBackList;
		CContainer *root;
		TZList m_Childrens;
		Zdib::CEventReceiver *myEventReceiver;
		virtual void SetOnFocus(CContainer *now)
		{}
	};
}